package main;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;


public class KeySignature {

	public static final String[] MAJOR_KEY_INDEX = {"C", "G", "D", "A", "E", "B", "F#", "Gb", "Db", "Ab", "Eb", "Bb", "F"};
	public static final String[] MINOR_KEY_INDEX = {"a", "e", "b", "f#", "c#", "g#", "d#", "eb", "bb", "f", "c", "g", "d"}; 
	public static final int[] SHARPS_FLATS = {0,1,2,3,4,5,6,-6,-5,-4,-3,-2,-1};
	private final String ACCIDENTAL_ORDER = "fcgdaeb";
	private final int SPACE_BETWEEN_SYMBOLS = 15;
	private final int FLAT_SIZE = 3*Score.BAR_LINE_SPACING+2*Score.BAR_LINE_WIDTH;
	private final int SHARP_SIZE = 2*Score.BAR_LINE_SPACING+2*Score.BAR_LINE_WIDTH;
	private final int FLAT_VERTICAL_OFFSET = 20;
	private final int SHARP_VERTICAL_OFFET = Score.NOTE_HEAD_SIZE/2;

	private boolean major;
	private Clef clef;
	private String keySignature;
	private Score score;
	private boolean sharps = true;
	private ArrayList<Character> accidentals = new ArrayList<Character>();
	private ArrayList<Integer> spacing = new ArrayList<Integer>();
	private Image sharp;
	private Image flat;

	/**
	 * 
	 * @param key Key signature
	 * @param c current clef
	 * @param s current score
	 */
	public KeySignature(String key, Clef c, Score s, boolean m){
		keySignature = key;
		clef = c;
		score = s;
		major = m;
		spacing = score.getSpacingList();
		evaluateKey();
		getImages();
	}

	/**
	 * Generate the sharp and flat images
	 */
	private void getImages() {
		MediaTracker tracker = new MediaTracker(score);
		try{
			sharp = ImageIO.read(new File("sharp.gif"));
			flat = ImageIO.read(new File("flat.gif"));
		}catch(IOException e){}
		tracker.addImage(sharp, 0);
		tracker.addImage(flat, 1);
		tracker.checkAll();
		//Scale the images
		sharp = sharp.getScaledInstance(-1,SHARP_SIZE, Image.SCALE_SMOOTH); 
		flat = flat.getScaledInstance(-1,FLAT_SIZE, Image.SCALE_SMOOTH);

	}

	/**
	 * Determine which key it is and how many sharps or flats it needs
	 */
	public void evaluateKey(){
		int index=0;
		String[] keyList = major? MAJOR_KEY_INDEX:MINOR_KEY_INDEX;
		for(int i = 0; i < keyList.length; i++){
			if (keyList[i].equals(keySignature)){
				index = i;
				break;
			}
		}
		int acc = SHARPS_FLATS[index];
		if(acc<0) sharps = false;
		//adds the note name for the accidentals to the accidentals list
		if(sharps)
			for(int i = 0; i < acc; i++)
				accidentals.add(ACCIDENTAL_ORDER.charAt(i));
		else
			for(int i = 0; i < Math.abs(acc); i++)
				accidentals.add(ACCIDENTAL_ORDER.charAt(ACCIDENTAL_ORDER.length()-(i+1)));
	}

	/**
	 * draw the key signature
	 * @param g graphics context
	 * @param hOff horizontal distance to begin drawing at
	 */
	public int draw(Graphics2D g, int hOff){
		Font curr = g.getFont();
		Font keyFont = new Font("SansSerif", Font.ITALIC, Score.NOTE_HEAD_SIZE);
		g.setFont(keyFont);
		Image img = sharps?sharp:flat;
		for(int i = 0; i < accidentals.size(); i++){
			char note = accidentals.get(i);
			int spaceIndex = Score.getPosition(note);
			int l = spacing.size()-1;
			int vOff = sharps?SHARP_VERTICAL_OFFET:FLAT_VERTICAL_OFFSET;
			g.drawImage(img, hOff, spacing.get(l-spaceIndex)-vOff, null);
			hOff += SPACE_BETWEEN_SYMBOLS; //increments the cursor to draw the next accidental
		}
		g.setFont(curr);
		int addition = accidentals.size()!=0?img.getWidth(null)/2:0;
		return hOff+addition;
	}

	/**
	 * @return in the key of x Major/minor
	 */
	public String toString(){
		String str = "" + keySignature;
		str += " " + (major? "Major":"minor");
		return str;
	}

}
